package self.Lunastic.HexaSweeper.Window;

import self.Lunastic.HexaSweeper.Base.UpdateLoop;
import self.Lunastic.HexaSweeper.Manager.GameManager;
import self.Lunastic.HexaSweeper.Base.GradientFunction;

import javax.swing.*;
import java.awt.*;
import java.util.*;

/**
 * 所有窗口的父类
 */
public class WindowBase extends JPanel {
    // 自动更新对象
    protected UpdateLoop updateLoop = new UpdateLoop(this::update, 1000/GameManager.TPS);
    public void setUpdate(){ this.updateLoop.set();}
    public void startUpdate(){ this.updateLoop.start();}
    public void stopUpdate(){ this.updateLoop.stop(); }
    public void endUpdate(){ this.updateLoop.end(); }

    // 板机 Map
    private final HashMap<String, Runnable> handlerMap = new HashMap<>();

    /**
     *  部署板机
     * @param handlerName 板机名称
     * @param handler 板机行为
     */
    public void setHandler (String handlerName, Runnable handler){
        this.handlerMap.put(handlerName, handler);
    }

    /**
     * 触发板机
     * @param handlerName 板机名称
     */
    public void doHandler (String handlerName){
        HashMap<String, Runnable> map = this.handlerMap;
        if(map.get(handlerName) != null) map.get(handlerName).run();
    }

    // 基础属性
    public int x, y;

    // 移动数据 （目标位置值, 位置差值, 倒计时）
    private int _x = 0, _y = 0, __x = 0, __y = 0;
    private double _moveTime = 0.0, __moveTime = 0.0;

    public WindowBase(int x,int y, int w, int h) {
        this.setLayout(null);
        this.x = x;this.y = y;
        this.setBounds(x, y, w, h);
        this.setOpaque(false);
        this.setUpdate();
    }

    // 移动更新
    private void moveUpdate(){
        this.x = this._x - (int)(GradientFunction.linear(this._moveTime/this.__moveTime) * this.__x);
        this.y = this._y - (int)(GradientFunction.linear(this._moveTime/this.__moveTime) * this.__y);
        this._moveTime --;
    }

    // 渲染
    private void draw(){
        this.setLocation(this.x, this.y);
        this.repaint();
    }

    // 更新内容
    public void update(){
        if(_moveTime > 0) moveUpdate();
    }

    @Override
    public void paintComponent(Graphics g) {
        this.draw();
        super.paintComponent(g);
    }

    /**
     * 向目标坐标移动
     * @param x 目标X
     * @param y 目标Y
     * @param millis 移动所需时间 (ms)
     */
    public void moveTo(int x, int y, int millis){
        this._x = x;
        this._y = y;
        if(millis > 0) {
            this._moveTime = 1.0*millis * GameManager.TPS / 1000;
            this.__x = x - this.x;
            this.__y = y - this.y;
            this.__moveTime = 1.0*millis * GameManager.TPS / 1000;
        }
    }
    public void moveToX(int x, int millis){this.moveTo(x,this.y,millis);}
    public void moveToY(int y, int millis){this.moveTo(this.x,y,millis);}
    public boolean isMoving(){return this._moveTime > 0;}

    /**
     * 开启所有组件
     */
    public void active(){
        for (Component c:this.getComponents()) { c.setEnabled(true); }
    }

    /**
     * 关闭所有组件
     */
    public void disactive(){
        for (Component c:this.getComponents()) { c.setEnabled(false); }
    }
}

